package com.matuw.android;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;

import com.matuw.android.log.QLogger;

import java.lang.reflect.Field;

/**
 * @author Shihwan
 * @date 2025/6/9
 */
public class QinSdk {

    public static final String LIBRARY_PREFIX = "awq_aos_sdk_";

    public static final String TAG = "QinSdk";

    private static boolean sDebuggable;

    private static boolean sLoggable;

    private static Application app;

    private volatile static boolean sGetAppByReflectError;

    public static void init(Context context) {
        if (context != null) {
            init(context, isDebuggable(context));
        }
    }

    public static void init(Context context, boolean debuggable) {
        init(context, debuggable, debuggable);
    }

    public static void init(Context context, boolean debuggable, boolean loggable) {
        app = (Application) (context instanceof Application ? context : context.getApplicationContext());
        sDebuggable = debuggable;
        sLoggable = loggable;
    }

    public static boolean isDebuggable() {
        return sDebuggable;
    }

    public static boolean isLoggable() {
        return sLoggable;
    }

    public static Application getApp() {
        Application app = QinSdk.app;
        if (app == null && !sGetAppByReflectError) {
            init(getApplicationByReflect());
        }

        return QinSdk.app;
    }

    @SuppressLint({"PrivateApi", "DiscouragedPrivateApi"})
    static Application getApplicationByReflect() {
        try {
            Class<?> clazz = Class.forName("android.app.ActivityThread");

            Field sCurrentActivityThreadField = clazz.getDeclaredField("sCurrentActivityThread");
            sCurrentActivityThreadField.setAccessible(true);
            Object obj = sCurrentActivityThreadField.get(null);

            Object thread = obj == null ? clazz.getMethod("currentActivityThread").invoke(null) : obj;

            if (thread == null) return null;

            Object app = clazz.getMethod("getApplication").invoke(thread);

            return app instanceof Application ? (Application) app : null;
        } catch (Throwable e) {
            sGetAppByReflectError = true;
            QLogger.w(TAG + "@GetApplicationByReflect.", e);
        }
        return null;
    }

    static boolean isDebuggable(Context context) {
        ApplicationInfo info = context.getApplicationInfo();
        return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
    }
}
